<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>企鹅语转换工具</title>
  <link rel="icon" href="https://078465.xyz/wp-content/uploads/2025/07/favicon.png">
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  
  <!-- Tailwind配置 -->
  <script>
    tailwind.config = {
      darkMode: 'class',
      theme: {
        extend: {
          colors: {
            primary: '#3b82f6',
            secondary: '#6366f1',
            accent: '#8b5cf6',
            dark: '#1e293b',
            light: '#f8fafc'
          },
          fontFamily: {
            inter: ['Inter', 'system-ui', 'sans-serif'],
          },
        },
      }
    }
  </script>

  <script>
    // On page load or when changing themes, best to add inline in `head` to avoid FOUC
    if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
      document.documentElement.classList.add('dark')
    } else {
      document.documentElement.classList.remove('dark')
    }
  </script>
  
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .text-shadow {
        text-shadow: 0 2px 4px rgba(0,0,0,0.1);
      }
      .bg-gradient {
        background: linear-gradient(135deg, #3b82f6 0%, #6366f1 50%, #8b5cf6 100%);
      }
      .transition-all-300 {
        transition: all 0.3s ease;
      }
      .hover-scale {
        transition: transform 0.2s ease;
      }
      .hover-scale:hover {
        transform: scale(1.02);
      }
    }
  </style>
</head>
<body class="font-inter bg-gray-50 dark:bg-slate-900 min-h-screen flex flex-col">
  <!-- 主要内容 -->
  <main class="flex-grow container mx-auto px-4 py-6 md:py-8">
    <!-- 标题区域 -->
    <div class="text-center mb-8 md:mb-12">
      <h2 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-dark dark:text-light mb-4 flex items-center justify-center">
        🐧企鹅语转换工具
        <a href="https://github.com/enKl03B/GugaTrans" target="_blank" rel="noopener noreferrer" class="ml-3 text-gray-600 dark:text-gray-400 hover:text-primary transition-all-300 text-[clamp(1.2rem,2.5vw,2.2rem)]">
          <i class="fa fa-github"></i>
        </a>
      </h2>
    </div>

    <!-- 转换工具卡片 -->
    <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-lg max-w-4xl mx-auto overflow-hidden hover-scale">
      <div class="bg-gradient p-4 md:p-6 text-white">
        <h3 class="text-xl font-bold flex items-center">
          <i class="fa fa-cogs mr-2"></i> 转换工具
        </h3>
      </div>
      
      <div class="p-4 md:p-6">
        <!-- 输入区域 -->
        <div class="mb-6">
          <div class="flex flex-col md:flex-row md:items-center justify-between mb-2">
            <label for="input-text" class="font-medium text-dark dark:text-light mb-2 md:mb-0">输入文本:</label>
            <div class="flex items-center space-x-2">
              <span id="char-counter" class="text-sm text-gray-500 dark:text-gray-400 mr-2">0 / 5000</span>
              <button id="clear-input" class="text-gray-500 dark:text-gray-400 hover:text-red-500 transition-all-300">
                <i class="fa fa-times-circle"></i> 清空
              </button>
              <button id="sample-text" class="text-gray-500 dark:text-gray-400 hover:text-primary transition-all-300">
                <i class="fa fa-file-text-o"></i> 示例
              </button>
            </div>
          </div>
          <textarea id="input-text" rows="6" class="w-full p-3 border border-gray-300 dark:border-slate-600 bg-white dark:bg-slate-700 dark:text-light rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary outline-none transition-all-300 resize-none dark:placeholder-gray-400" placeholder="请输入要转换的文本..."></textarea>
        </div>
        
        <!-- 操作按钮 -->
        <div class="flex flex-wrap gap-3 justify-center mb-6">
          <button id="encode-btn" class="flex-1 md:flex-none bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all-300 shadow-md hover:shadow-lg flex items-center justify-center">
            <i class="fa fa-lock mr-2"></i> 编码
          </button>
          <button id="decode-btn" class="flex-1 md:flex-none bg-secondary hover:bg-secondary/90 text-white font-medium py-2 px-6 rounded-lg transition-all-300 shadow-md hover:shadow-lg flex items-center justify-center">
            <i class="fa fa-unlock mr-2"></i> 解码
          </button>
          <button id="swap-btn" class="flex-none bg-gray-200 dark:bg-slate-600 hover:bg-gray-300 dark:hover:bg-slate-500 text-gray-700 dark:text-slate-200 py-2 px-4 rounded-lg transition-all-300 flex items-center justify-center">
            <i class="fa fa-exchange mr-2"></i> 交换
          </button>
          <button id="penguin-button" class="flex-none bg-blue-200 dark:bg-blue-600 hover:bg-blue-300 dark:hover:bg-blue-500 text-blue-700 dark:text-blue-200 py-2 px-4 rounded-lg transition-all-300 flex items-center justify-center text-lg">
            🐧
          </button>
        </div>
        
        <!-- 输出区域 -->
        <div>
          <div class="flex flex-col md:flex-row md:items-center justify-between mb-2">
            <label for="output-text" class="font-medium text-dark dark:text-light mb-2 md:mb-0">转换结果:</label>
            <div class="flex space-x-2">
              <button id="copy-output" class="text-gray-500 dark:text-gray-400 hover:text-green-500 transition-all-300">
                <i class="fa fa-clipboard"></i> 复制
              </button>
            </div>
          </div>
          <div class="relative">
            <textarea id="output-text" rows="6" class="w-full p-3 border border-gray-300 dark:border-slate-600 bg-white dark:bg-slate-700 dark:text-light rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary outline-none transition-all-300 resize-none dark:placeholder-gray-400" placeholder="转换结果将显示在这里..." readonly></textarea>
            <div id="toast-notification" class="absolute -top-10 right-4 bg-green-500 text-white py-1 px-3 rounded-lg shadow-lg opacity-0 transition-all-300">
                <span></span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 编码规则说明 -->
    <div class="mt-12 max-w-4xl mx-auto">
      <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-lg overflow-hidden hover-scale">
        <div class="bg-dark p-4 md:p-6 text-white">
          <h3 class="text-xl font-bold flex items-center">
            <i class="fa fa-book mr-2"></i> 编码规则说明
          </h3>
        </div>
        
        <div class="p-4 md:p-6">
          <div class="space-y-4">
            <div>
              <h4 class="font-bold text-lg text-primary mb-2">Base64 符号映射</h4>
              <p>本工具使用 "咕"、"嘎"、"🐧"、"🍄"、"哇擦" 作为基础字符集，通过组合这些字符表示标准 Base64 的 64 个符号：</p>
              <ul class="list-disc pl-5 space-y-1 text-gray-700 dark:text-gray-300">
                <li><span class="font-medium">单个字符</span>：咕、嘎、🐧、🍄 表示前 4 个符号 (A-D)</li>
                <li><span class="font-medium">双字符组合</span>：包括 "哇擦" 开头的组合，如 哇擦咕、哇擦嘎... 表示接下来的 10 个符号 (E-N)</li>
                <li><span class="font-medium">三字符组合</span>：使用三个字符的排列组合表示剩余 50 个符号</li>
              </ul>
            </div>
            
            <div>
              <h4 class="font-bold text-lg text-primary mb-2">编码流程</h4>
              <ol class="list-decimal pl-5 space-y-1 text-gray-700 dark:text-gray-300">
                <li>将输入文本转换为二进制数据</li>
                <li>每 3 字节（24 位）分为一组，不足则补零</li>
                <li>每组按 6 位分割为 4 个值（0-63）</li>
                <li>每个值映射为对应的 "咕/嘎/🐧/🍄/哇擦" 字符组合</li>
              </ol>
            </div>
            
            <div>
              <h4 class="font-bold text-lg text-primary mb-2">示例</h4>
              <p class="mb-2">标准 Base64 编码 "hello" 结果为 "aGVsbG8="，对应的自定义编码为：</p>
              <div class="bg-gray-100 dark:bg-slate-700 p-3 rounded-lg overflow-x-auto">
                <pre class="text-gray-800 dark:text-gray-200">嘎咕嘎嘎嘎嘎咕哇擦嘎嘎🍄哇擦嘎咕🐧咕嘎嘎🐧🐧咕</pre>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </main>

  <!-- JavaScript -->
  <script>
    // DOM元素
    const inputText = document.getElementById('input-text');
    const outputText = document.getElementById('output-text');
    const encodeBtn = document.getElementById('encode-btn');
    const decodeBtn = document.getElementById('decode-btn');
    const swapBtn = document.getElementById('swap-btn');
    const clearInputBtn = document.getElementById('clear-input');
    const sampleTextBtn = document.getElementById('sample-text');
    const copyOutputBtn = document.getElementById('copy-output');
    const toast = document.getElementById('toast-notification');
    const charCounter = document.getElementById('char-counter');
    const penguinButton = document.getElementById('penguin-button');
    
    const MAX_INPUT_LENGTH = 5000;
    let penguinClickCount = 0;
    const penguinAudio = new Audio('https://078465.xyz/wp-content/uploads/2025/07/gugugaga.mp3');

    // 初始化Web Worker
    const worker = new Worker('worker.js');

    function showToast(message, isError = false) {
      const toastSpan = toast.querySelector('span');
      toastSpan.innerHTML = message;
      toast.classList.remove('bg-green-500', 'bg-red-500');
      toast.classList.add(isError ? 'bg-red-500' : 'bg-green-500');
      
      toast.style.opacity = '1';
      setTimeout(() => {
        toast.style.opacity = '0';
      }, 2500);
    }
    
    function updateCharCounter() {
      const currentLength = Array.from(inputText.value).length;
      charCounter.textContent = `${currentLength} / ${MAX_INPUT_LENGTH}`;
      if (currentLength > MAX_INPUT_LENGTH) {
        charCounter.classList.add('text-red-500', 'font-bold');
        } else {
        charCounter.classList.remove('text-red-500', 'font-bold');
        }
      }

    inputText.addEventListener('input', () => {
      updateCharCounter();
    });

    function setProcessing(isProcessing) {
      encodeBtn.disabled = isProcessing;
      decodeBtn.disabled = isProcessing;
      swapBtn.disabled = isProcessing;

      if (!isProcessing) {
        encodeBtn.innerHTML = '<i class="fa fa-lock mr-2"></i> 编码';
        decodeBtn.innerHTML = '<i class="fa fa-unlock mr-2"></i> 解码';
        swapBtn.innerHTML = '<i class="fa fa-exchange mr-2"></i> 交换';
      }
    }
    
    // 事件监听器
    encodeBtn.addEventListener('click', () => {
      const charArray = Array.from(inputText.value);
      if (charArray.length > MAX_INPUT_LENGTH) {
        inputText.value = charArray.slice(0, MAX_INPUT_LENGTH).join('');
        updateCharCounter();
        showToast('<i class="fa fa-warning mr-1"></i> 输入已截断至上限', true);
      }

      if (inputText.value.trim() === '') {
        outputText.value = '请输入要编码的文本';
        return;
      }
      
      setProcessing(true);
      encodeBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i> 正在编码...';
      const inputBytes = new TextEncoder().encode(inputText.value).buffer;
      worker.postMessage({ type: 'encode', input: inputBytes }, [inputBytes]);
    });
    
    decodeBtn.addEventListener('click', () => {
      const charArray = Array.from(inputText.value);
      if (charArray.length > MAX_INPUT_LENGTH) {
        inputText.value = charArray.slice(0, MAX_INPUT_LENGTH).join('');
        updateCharCounter();
        showToast('<i class="fa fa-warning mr-1"></i> 输入已截断至上限', true);
      }

      if (inputText.value.trim() === '') {
        outputText.value = '请输入要解码的自定义Base64';
        return;
      }
      
      setProcessing(true);
      decodeBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i> 正在解码...';
      const inputBytes = new TextEncoder().encode(inputText.value).buffer;
      worker.postMessage({ type: 'decode', input: inputBytes }, [inputBytes]);
    });

    // 监听来自Worker的消息
    worker.onmessage = function(e) {
      setProcessing(false);
      const { status, type, result, message } = e.data;

      if (status === 'success') {
        const resultText = new TextDecoder().decode(result);
        outputText.value = resultText;
      } else {
        const action = type === 'encode' ? '编码' : '解码';
        outputText.value = `${action}错误: ${message}`;
      }
    };
    
    swapBtn.addEventListener('click', () => {
      setProcessing(true);
      swapBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i> 交换中...';

      setTimeout(() => {
      const temp = inputText.value;
      inputText.value = outputText.value;
      outputText.value = temp;
        updateCharCounter();
        setProcessing(false);
      }, 10);
    });
    
    clearInputBtn.addEventListener('click', () => {
      inputText.value = '';
      outputText.value = '';
      updateCharCounter();
      inputText.focus();
    });
    
    sampleTextBtn.addEventListener('click', () => {
      inputText.value = 'hello';
      outputText.value = '嘎咕嘎咕嘎嘎咕哇擦嘎嘎🍄哇擦嘎咕🐧咕嘎嘎🐧🐧咕';
      updateCharCounter();
    });
    
    copyOutputBtn.addEventListener('click', () => {
      if (outputText.value.trim() === '') return;
      
      outputText.select();
      document.execCommand('copy');
      
      showToast('<i class="fa fa-check mr-1"></i> 已复制!');
    });

    penguinButton.addEventListener('click', () => {
      penguinClickCount++;
      if (penguinClickCount === 3) {
        penguinAudio.play();
        penguinClickCount = 0; // Reset count after playing
      } else {
        // Optionally, provide feedback on remaining clicks
        // showToast(`再点击 ${3 - penguinClickCount} 次播放🐧音频`, false);
      }
    });

    // Listen for system theme changes
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
        if (e.matches) {
            document.documentElement.classList.add('dark');
        } else {
            document.documentElement.classList.remove('dark');
        }
    });
    
    // 初始化
    updateCharCounter();
    sampleTextBtn.click();
  </script>
</body>
</html>
    